package com.fuxinglianbao.services;

import com.fuxinglianbao.models.StarLevel;
import com.fuxinglianbao.models.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class StarLevelService {
    @Autowired
    private EntityManager entityManager;

    @Autowired
    private UserService userService;

    @Transactional(readOnly = true)
    public StarLevel getStarLevel(int level) {
        return entityManager.find(StarLevel.class, level);
    }

    @Transactional
    public void initializeStarLevels() {
        if (isStarLevelsInitialized()) {
            return;
        }

        // 初始化星级配置
        entityManager.persist(StarLevel.create(1, 100, 140, 100));
        entityManager.persist(StarLevel.create(2, 240, 196, 140));
        entityManager.persist(StarLevel.create(3, 436, 274, 196));
        entityManager.persist(StarLevel.create(4, 710, 384, 274));
        entityManager.persist(StarLevel.create(5, 1094, 538, 384));
        entityManager.persist(StarLevel.create(6, 1632, 753, 538));
        entityManager.persist(StarLevel.create(7, 2385, 1054, 753));
        entityManager.persist(StarLevel.create(8, 3439, 1476, 1054));
        entityManager.persist(StarLevel.create(9, 4915, 2066, 1476));
        entityManager.persist(StarLevel.create(10, 6981, 2893, 2066));
        entityManager.persist(StarLevel.create(11, 9874, 4050, 2893));
        entityManager.persist(StarLevel.create(12, 13924, 5669, 4050));
    }

    private boolean isStarLevelsInitialized() {
        Long count = entityManager.createQuery(
                "SELECT COUNT(s) FROM StarLevel s", Long.class)
                .getSingleResult();
        return count > 0;
    }

    @Transactional
    public User directPreCharge(Long userId, int targetStarLevel) {
        User user = userService.getUser(userId);
        StarLevel starLevel = getStarLevel(targetStarLevel);
        
        if (starLevel == null) {
            throw new IllegalArgumentException("目标星级不存在");
        }
        
        if (user.getStarLevel() >= targetStarLevel) {
            throw new IllegalArgumentException("目标星级不能低于当前星级");
        }

        // 设置新的星级
        user.setStarLevel(targetStarLevel);
        user.setStarLevelActivationTime(LocalDateTime.now());

        return entityManager.merge(user);
    }

    @Transactional
    public User upgradeByDifference(Long userId, int targetStarLevel) {
        User user = userService.getUser(userId);
        StarLevel currentLevel = getStarLevel(user.getStarLevel());
        StarLevel targetLevel = getStarLevel(targetStarLevel);

        if (targetLevel == null) {
            throw new IllegalArgumentException("目标星级不存在");
        }

        if (user.getStarLevel() >= targetStarLevel) {
            throw new IllegalArgumentException("目标星级不能低于当前星级");
        }

        BigDecimal difference = targetLevel.getPreChargeAmount()
                .subtract(currentLevel.getPreChargeAmount());

        // 设置新的星级
        user.setStarLevel(targetStarLevel);
        user.setStarLevelActivationTime(LocalDateTime.now());

        return entityManager.merge(user);
    }

    @Transactional
    public User automaticUpgrade(Long userId) {
        User user = userService.getUser(userId);
        int currentLevel = user.getStarLevel();
        StarLevel nextLevel = getStarLevel(currentLevel + 1);

        if (nextLevel == null) {
            throw new IllegalArgumentException("已达到最高星级");
        }

        // 设置新的星级
        user.setStarLevel(currentLevel + 1);
        user.setStarLevelActivationTime(LocalDateTime.now());

        return entityManager.merge(user);
    }

    @Transactional(readOnly = true)
    public BigDecimal calculateUpgradeCost(int currentStarLevel, int targetStarLevel) {
        if (currentStarLevel >= targetStarLevel) {
            throw new IllegalArgumentException("目标星级必须高于当前星级");
        }

        StarLevel current = getStarLevel(currentStarLevel);
        StarLevel target = getStarLevel(targetStarLevel);

        if (current == null || target == null) {
            throw new IllegalArgumentException("星级配置不存在");
        }

        return target.getPreChargeAmount().subtract(current.getPreChargeAmount());
    }
}